<template>
    <div class="view_menu">
        <card title="菜单管理">
            <template #actions>
                <el-button type="primary" @click="add">添加菜单</el-button>
            </template>
            <template #default>
                <el-table :data="tableData" row-key="menuId" :tree-props="{ children: 'childs' }">
                    <el-table-column label="菜单名" prop="name" />
                    <el-table-column label="类型">
                        <template v-slot="{ row: { type } }">
                            <el-tag effect="dark" :type="menuTypes[type].tagType">
                                {{ menuTypes[type].label }}
                            </el-tag>
                        </template>
                    </el-table-column>
                    <el-table-column label="图标" prop="icon" />
                    <el-table-column label="排序" prop="seq" />
                    <el-table-column label="路由地址" prop="url" />
                    <el-table-column label="授权标识" prop="perms" />
                    <el-table-column label="操作">
                        <template v-slot="{ row }">
                            <el-button type="text" @click="edit(row)">编辑</el-button>
                            <el-button type="text" @click="_delete(row.menuId)">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </template>
        </card>

        <!-- 添加/编辑菜单对话框 -->
        <el-dialog :visible.sync="visible" @closed="handleClosed">
            <template #default>
                <el-tabs v-model="$menuType">
                    <el-tab-pane v-for="(val, key) in menuTypes" :key="key" :name="key" :label="val.label" />
                </el-tabs>
                <el-alert type="danger">目录和菜单的父级只能是目录，权限的父级只能是菜单，切勿随意操作权限</el-alert>
                <el-form label-position="top">
                    <el-row :gutter="24">
                        <el-col :span="12">
                            <el-form-item :label="menuTypes[formData.type].label + '名'">
                                <el-input v-model="formData.name" />
                            </el-form-item>
                            <el-form-item label="图标">
                                <el-input v-model="formData.icon" />
                            </el-form-item>
                        </el-col>
                        <el-col :span="12">
                            <el-form-item label="父级">
                                <treeselect
                                    :options="menuOptions"
                                    v-model="formData.parentId"
                                    :normalizer="normalizer"
                                    append-to-body
                                    zIndex="3000"
                                />
                            </el-form-item>
                            <el-form-item label="排序">
                                <el-input v-model="formData.seq" type="number" min="0" max="99" />
                            </el-form-item>
                        </el-col>
                    </el-row>
                    <template v-if="formData.type == 1">
                        <el-form-item label="路由地址">
                            <el-input v-model="formData.url" />
                        </el-form-item>
                    </template>
                    <template v-else-if="formData.type == 2">
                        <el-row :gutter="24">
                            <el-col :span="12">
                                <el-form-item label="授权方法">
                                    <el-select v-model="formData.method">
                                        <el-option label="GET" value="GET" />
                                        <el-option label="POST" value="POST" />
                                        <el-option label="PUT" value="PUT" />
                                        <el-option label="DELETE" value="DELETE" />
                                    </el-select>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="授权">
                                    <el-input v-model="formData.perms" />
                                </el-form-item>
                            </el-col>
                        </el-row>
                    </template>
                </el-form>
            </template>
            <template #footer>
                <el-button type="primary" @click="save">保存</el-button>
            </template>
        </el-dialog>
    </div>
</template>

<script>
import { getDeletionOptions, getQueryOptions } from '../../mixins';
import treeselect from '@riophae/vue-treeselect';

const defaultFormData = {
    type: 0,
    name: '',
    icon: '',
    parentId: 0,
    url: '',
    perms: '',
    method: '',
    seq: 99,
};
const defaultFormDataCopied = Object.assign({}, defaultFormData);

export default {
    data() {
        return {
            visible: false,
            editing: false,

            tableData: [],

            formData: defaultFormData,

            normalizer(node) {
                return node.childs && node.childs.length
                    ? {
                          id: node.menuId,
                          label: node.name,
                          children: node.childs,
                      }
                    : { id: node.menuId, label: node.name };
            },
        };
    },

    components: { treeselect },

    mixins: [
        getQueryOptions({
            apiurl: '/yxl/menu/findMenu',
        }),

        getDeletionOptions({
            apiurl: '/yxl/menu/deleteMenu',
            params: 'menuId',
        }),
    ],

    computed: {
        // 表单数据菜单类型绑定
        $menuType: {
            get() {
                return this.formData.type.toString();
            },

            set(v) {
                this.formData.type = +v;
            },
        },

        // 菜单选项
        menuOptions() {
            const menus = JSON.parse(JSON.stringify(this.tableData));

            const filteredMenus = menus.filter(function filter(menu) {
                if (menu.childs && menu.type !== 2) {
                    menu.childs = menu.childs.filter(filter);
                    return true;
                }
            });

            return [{ menuId: 0, name: '根目录' }].concat(filteredMenus);
        },

        // 菜单类型
        menuTypes() {
            return {
                0: { tagType: 'default', label: '目录' },
                1: { tagType: 'success', label: '菜单' },
                2: { tagType: 'danger', label: '权限' },
            };
        },
    },

    methods: {
        // 添加
        add() {
            this.editing = false;
            this.visible = true;
        },

        // 编辑
        edit(row) {
            this.editing = true;

            this.formData.menuId = row.menuId;
            this.formData.name = row.name;
            this.formData.parentId = row.parentId;
            this.formData.seq = row.seq;
            this.formData.type = row.type;
            this.formData.icon = row.icon;
            this.formData.method = row.method;
            this.formData.perms = row.perms;
            this.formData.url = row.url;

            this.visible = true;
        },

        // 保存
        save() {
            let data = Object.assign({}, this.formData);
            if (data.type == 0) {
                delete data.url, delete data.perms, delete data.method;
            } else if (data.type == 1) {
                delete data.perms, delete data.method;
            } else if (data.type == 2) {
                delete data.url;
            }

            this.$put(`/yxl/menu/${this.editing ? 'update' : 'save'}Menu`, data).then(res => {
                this.visible = false;
                this.$root.getAdministratorRoutes();
                this.query();
            });
        },

        // 处理对话框关闭
        handleClosed() {
            delete this.formData.menuId;
            Object.assign(this.formData, defaultFormDataCopied);
        },
    },
};
</script>